﻿using System;
using System.Diagnostics;
using System.Globalization;
using System.Windows.Forms;
using ComClassLibrary;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using LogLib;
using SoftKeyBoard;
using System.IO.Pipes;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms.Integration;
using System.Windows.Interop;
using InputTool;
using KeyboardArg;
using CountrySelectionKeyBoard;

namespace KeyboardManager
{
    public partial class FormManager : Form
    {
        protected IntPtr ParentFormHandle = IntPtr.Zero;

        private int _errorCount = 0;

        /// <summary>
        /// 指示当前的软键盘是否处于被激活状态
        /// </summary>
        private bool _isKeyboardActived = false;

        private const string ToolName = "FormManager";

        private IntPtr SenderFormHandle = IntPtr.Zero;

        private FormInputTool _inputTool = null;

        //软键盘帮助类的对象
        private SoftKeyHelper SKHelper = new SoftKeyHelper();

        /// <summary>
        /// 自定义通知消息(指示键盘已经退出)
        /// </summary>
        private const int MSG_NOTIFY_EXIT = 0x400 + 1;

        private string CalendarAppPath = "";
        public FormManager(string arg)
        {
            InitializeComponent();
            if (!string.IsNullOrEmpty(arg))
            {
                ParentFormHandle = (IntPtr)Int32.Parse(arg);
            }
           CreatAllKindOfKeyBoard();
        }

        public FormManager()
        {
            InitializeComponent();
            CreatAllKindOfKeyBoard();
        }

        private void CreatAllKindOfKeyBoard()
        {          
            CalendarAppPath = Path.Combine(Application.StartupPath, "CalendarBoard.exe");
            _inputTool = new FormInputTool();
            _inputTool.Hidden += OnWndHidden;
        }

        private void OnWndHidden(object sender, EventArgs e)
        {
            _isKeyboardActived = false;
        }
        private void InputpassportNumber(KeyBoardArgs args)
        {
            FormInputPassportNumber form = new FormInputPassportNumber(args);
            form.ShowDialog();
            form.Dispose();
            form = null;
            GC.Collect();
        }

        private void InputLetterNumber(KeyBoardArgs args)
        {
            FormKeyInputing form = new FormKeyInputing(args);
            form.ShowDialog();
            form.Dispose();
            form = null;
            GC.Collect();
        }

        private void InputPhoneNumber(KeyBoardArgs args)
        {
            FormInputPhoneNumber form = new FormInputPhoneNumber(args);
            form.ShowDialog();
            form.Dispose();
            form = null;
            GC.Collect();
        }

        private void SelectKeyWord(KeyBoardArgs args)
        {
            MainWindow window = new MainWindow(args);
            window.ShowDialog();
            window = null;
            GC.Collect();
        }

        private void SelectCountry(KeyBoardArgs args)
        {
            CountrySelectionKeyBoard.MainWindow window = new CountrySelectionKeyBoard.MainWindow(args);
            window.ShowDialog();
            window = null;
            GC.Collect();
        }

        private void InputIDCardNumber(KeyBoardArgs args)
        {
            FormInputID form = new FormInputID(args);
            form.ShowDialog();
            form.Dispose();
            form = null;
            GC.Collect();
        }

        private void InputCommonText(KeyBoardArgs args)
        {
            _inputTool.SetInputToolArg(args);
            _inputTool.Show();
        }

        private void SelectDateTime(KeyBoardArgs args)
        {
            FormCalender form = new FormCalender(args);
            form.ShowDialog();
            form.Dispose();
            form = null;
            GC.Collect();
        }

        private void FormKeyBoardManager_Load(object sender, EventArgs e)
        {
            this.Opacity = 1;
            OnAppStartupFinished();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (SKHelper.IsKeyboardOpen())
            {
                SKHelper.CloseKeyBoard();
            }
            SKHelper.OpenKeyBoard();
            //txbPsw.Focus();    //如果需要打开软键盘的同时使得某个输入框获得焦点，则此处可以调用Focus()方法
        }

        private void button2_Click(object sender, EventArgs e)
        {
            IntPtr intPtr = SKHelper.GetKeyboardWindowHandle();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            long ret = SKHelper.CheckIsTopMost();
            MessageBox.Show(string.Format("{0}", ret));
        }

        protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                case (int)MessageType.WM_COPYDATA:
                    OnKeyBoardMsgReceived(m);
                    break;
                case MSG_NOTIFY_EXIT:
                    _isKeyboardActived = false;
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }

        protected void OnKeyBoardMsgReceived(System.Windows.Forms.Message m)
        {
            COPYDATASTRUCT_INTPTR cds = new COPYDATASTRUCT_INTPTR();
            Type mytype = cds.GetType();
            cds = (COPYDATASTRUCT_INTPTR)m.GetLParam(mytype);
            uint flag = (uint)(cds.dwData);
            byte[] data = new byte[cds.cbData];
            Marshal.Copy(cds.lpData, data, 0, data.Length);
            string jsonString = System.Text.Encoding.UTF8.GetString(data);
            jsonString = jsonString.Replace('@', '"');
            Log.WriteAsync("Get Json:" + jsonString);
            KeyBoardArgs ret = null;
            try
            {
                ret = JsonHandler.ConvertToJsonObject<KeyBoardArgs>(jsonString);
                switch (ret.PassageType)
                {
                    case SendMessageType.Request:
                        OnRequestProcessing(ret);
                        break;
                    case SendMessageType.Response:
                        OnResponseProcessing(ret);
                        break;
                    case SendMessageType.Exit:
                        this.Close();
                        break;
                    default:
                        break;
                }
            }
            catch(Exception ex)
            {
                Log.WriteException(ex.ToString());
            }
        }

        /// <summary>
        /// 处理软键盘请求类型消息
        /// </summary>
        /// <param name="args"></param>
        private void OnRequestProcessing(KeyBoardArgs args)
        {
            if (args == null)
            {
                return;
            }
            if (_isKeyboardActived)
            {
                _errorCount++;
                if (_errorCount <= 6)
                {
                    Log.WriteAsync("检测到键盘处于激活状态，忽略此次激活.");
                    return;
                }
            }
            _errorCount = 0;
            if(string.IsNullOrEmpty(args.DictionaryFileName)) // 使用默认手写键盘
            {
                InputCommonText(args);
            }           
            else if (args.DictionaryFileName.StartsWith("Date")) // 使用日期选择键盘
            {
                SelectDateTime(args);
            }
            else if (args.DictionaryFileName.Equals("Number")) 
            {
                InputIDCardNumber(args);
            }
            else if(args.DictionaryFileName.Equals("IDCard") ) // 使用号码输入键盘
            {
                InputIDCardNumber(args);
            }
            else if (args.DictionaryFileName.Equals("Phone")) // 使用号码输入键盘
            {
                InputPhoneNumber(args);
            }         
            else if(args.DictionaryFileName.Equals("Passport"))               
            {
                if(args.Key.Equals("HZ") || args.Key.Equals("GAZ") || args.Key.Equals("TWZ"))
                {
                    InputpassportNumber(args);
                }               
            }
            else if (args.DictionaryFileName.Equals("Letter"))
            {
                InputLetterNumber(args);
            }
            else if (args.DictionaryFileName.Equals("QWD"))
            {
                SelectCountry(args);
            }
            else
            {
                SelectKeyWord(args);
            }
        }

        /// <summary>
        /// 处理软键盘回答类型消息
        /// </summary>
        /// <param name="ret"></param>
        private void OnResponseProcessing(KeyBoardArgs ret)
        {
            if (null == ret)
            {
                return;
            }
            TextBox box = null;
            Control ctl = this.Controls[ret.SenderName];
            if(!(ctl is TextBox))
            {
                return;
            }
            box = ctl as TextBox;
            box.Text = ret.Content;           
            if (ret.Key == "CSD" || ret.Key == "Citys" || ret.Key == "Address")
            {
                box.Text = ret.FullContent;
            }         
            if (ret.DictionaryFileName.StartsWith("Date"))
            {
                DateTime dt = DateTime.Parse(ret.Content);
                textBoxDateTime.Text = dt.ToString("yyyy-MM-dd");
            }         
        }

        private void textBoxXM_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxXM.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 5;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxXM.Text;
            arg.Title = "请输入你的测试姓名";
            arg.Key = "XM";
            OnRequestProcessing(arg);
        }

        private void textBoxJiGuan_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxJiGuan.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 12;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxJiGuan.Text;
            arg.Title = "请选择籍贯";
            arg.Key = "CSD";
            arg.LanguageCode = "zh-CN";
            //arg.DictionaryFileName = "AccommodationType";
            //arg.DictionaryFileName = "Careers";
            //arg.DictionaryFileName = "Citys";
            //arg.DictionaryFileName = "IDType";
            //arg.DictionaryFileName = "Nationality";
            //arg.DictionaryFileName = "ResidenceCertificateType";
            //arg.DictionaryFileName = "StayPurpose";
            //arg.DictionaryFileName = "Sex";
            //arg.DictionaryFileName = "Sex";
            //arg.DictionaryFileName = "EducationDegree";
            //arg.DictionaryFileName = "MaritalStatus";
            //arg.DictionaryFileName = "Nation";
            arg.DictionaryFileName = "NativePlace";
            //arg.DictionaryFileName = "Profession";
            //arg.DictionaryFileName = "ResidencePurpose";
            //arg.DictionaryFileName = "StayPlace";
            //arg.DictionaryFileName = "ShiXian";
            OnRequestProcessing(arg);
        }

        private void textBoxDateTime_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxDateTime.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 18;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Key = (string)textBoxDateTime.Tag;
            arg.DictionaryFileName = "DateTime";
            arg.LanguageCode = "zh-CN";
            arg.Title = "请选择出生日期";
            arg.Content = "2019-05-22";
            OnRequestProcessing(arg);
        }

        private void FormManager_FormClosing(object sender, FormClosingEventArgs e)
        {      
            Log.Exit();
        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }

        private void textBoxIDCard_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.Content = textBoxIDCard.Text;
            arg.SenderName = textBoxIDCard.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 18;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Key = (string)textBoxIDCard.Tag;
            arg.DictionaryFileName = "IDCard";
            arg.LanguageCode = "zh-CN";
            arg.Title = "请输入身份证号码";
            OnRequestProcessing(arg);
        }

        private void textBoxPhone_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.Content = textBoxPhone.Text;
            arg.SenderName = textBoxPhone.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 18;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Key = "PhoneNumber";
            arg.DictionaryFileName = "PhoneNumber";
            arg.LanguageCode = "zh-CN";
            arg.Title = "请输入电话号码";
            OnRequestProcessing(arg);
        }

        private void button4_Click(object sender, EventArgs e)
        {
         
             int  LCTYPE = 4;
            StringBuilder S = new StringBuilder(255);
            //中文(简体)
            int d = ComClassLibrary.WinAPI.GetLocaleInfo(2048, LCTYPE, S, 255);
            MessageBox.Show(S.ToString());
        }

        private void button5_Click(object sender, EventArgs e)
        {
            int LCTYPE = 1;
            //StringBuilder S = new StringBuilder(255);
           // S.Append("0409");
            string S = "0409";
            //中文(简体)
            int d = ComClassLibrary.WinAPI.SetLocaleInfo(2048, LCTYPE, S);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            int ret = ComClassLibrary.WinAPI.GetSystemDefaultLCID();
        }

        private void textBoxDetailedAddress_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxDetailedAddress.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 12;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = "";
            arg.Title = "请选择地址";
            arg.Key = "Address";
            arg.LanguageCode = "zh-CN";
            //arg.DictionaryFileName = "AccommodationType";
            //arg.DictionaryFileName = "Careers";
            //arg.DictionaryFileName = "Citys";
            //arg.DictionaryFileName = "IDType";
            //arg.DictionaryFileName = "Nationality";
            arg.Tag = (string)textBoxStandardAddress.Tag;
            arg.DictionaryFileName = "StandardAddress";
            //arg.DictionaryFileName = "StayPurpose";
            //arg.DictionaryFileName = "Sex";
            OnRequestProcessing(arg);
        }

        private void textBoxStandardAddress_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxStandardAddress.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 12;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = "";
            arg.Tag = (string)textBoxStandardAddress.Tag;
            arg.Title = "请选择地址";
            arg.Key = "Citys";
            arg.LanguageCode = "zh-CN";
            //arg.DictionaryFileName = "AccommodationType";
            //arg.DictionaryFileName = "Careers";
            arg.DictionaryFileName = "Citys";
            //arg.DictionaryFileName = "IDType";
            //arg.DictionaryFileName = "Nationality";
            //arg.DictionaryFileName = "StandardAddress";
            //arg.DictionaryFileName = "StayPurpose";
            //arg.DictionaryFileName = "Sex";
            OnRequestProcessing(arg);
        }

        private void button7_Click_1(object sender, EventArgs e)
        {
            string str = "معلومات التأشيرة لا تتطابق مع معلومات جواز السفر, يرجى إعادة التقديم أو الاتصال بالموظفين, هاتف:02750777176";
            //MessageBox.Show(str);
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.Title = str;
            string parm = JsonHandler.ConvertToJsonString(arg);
            KeyBoardArgs arg2 = JsonHandler.ConvertToJsonObject<KeyBoardArgs>(parm);
        }

        #region Notify MainForm about something
        private string _appName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().CodeBase);
        /// <summary>
        /// 通知主窗体该进程启动已经完成
        /// </summary>
        protected void OnAppStartupFinished()
        {
            // 当父窗体为空时，不需要通知
            if (ParentFormHandle == IntPtr.Zero)
                return;
            string sendMsg = string.Format("{0}#{1}#程序已加载成功", _appName, 1);
            PipeClient t = new PipeClient(8, sendMsg);
            Task.Factory.StartNew(new Action(t.run));
            Log.WriteAsync("已经通知主窗体启动完成: " + _appName);
        }
        #endregion

        private void TextBoxGAZ_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxGAZ.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 5;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxGAZ.Text;
            arg.Title = "请输入港澳证号码";
            arg.DictionaryFileName = "Passport";
            arg.Key = "GAZ";
            OnRequestProcessing(arg);
        }

        private void TextBoxPassport_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxPassport.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 5;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxPassport.Text;
            arg.Title = "请输入护照号码";
            arg.DictionaryFileName = "Passport";
            arg.Key = "HZ";
            OnRequestProcessing(arg);
        }

        private void TextBoxTWZ_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxTWZ.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 5;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxTWZ.Text;
            arg.Title = "请输入台湾证号码";
            arg.DictionaryFileName = "Passport";
            arg.Key = "TWZ";
            OnRequestProcessing(arg);
        }

        private void textBoxLetterNumber_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxLetterNumber.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 8;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxLetterNumber.Text;
            arg.Title = "请输入香港身份证号码";
            arg.DictionaryFileName = "Letter";
            arg.Key = "";
            arg.Tag = "";
            OnRequestProcessing(arg);
        }

        private void textBoxCJSY_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxCJSY.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 16;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxCJSY.Text;
            arg.Title = "请选择出境事由";
            arg.DictionaryFileName = "CJSY";
            arg.Key = "";
            arg.Tag = "";
            OnRequestProcessing(arg);
        }

        private void textBoxZY_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxZY.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 16;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxZY.Text;
            arg.Title = "请选择职业";
            arg.DictionaryFileName = "ZY";
            arg.Key = "";
            arg.Tag = "";
            OnRequestProcessing(arg);
        }

        private void textBoxCountry_Enter(object sender, EventArgs e)
        {
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxCountry.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 16;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = textBoxCountry.Text;
            arg.Title = "请选择前往地";
            arg.DictionaryFileName = "QWD";
            arg.Key = "";
            arg.Tag = "";
            OnRequestProcessing(arg);
        }

        private void txbCSD_Enter(object sender, EventArgs e)
        {
            
            KeyBoardArgs arg = new KeyBoardArgs();
            arg.SenderName = textBoxDetailedAddress.Name;
            arg.PassageType = SendMessageType.Request;
            arg.MaxLength = 12;
            arg.SenderHandle = this.Handle;
            arg.MsgReceiver = this.Handle;
            arg.Content = "";
            arg.Title = "请选择地址";
            arg.Key = "CSD";
            arg.LanguageCode = "zh-CN";
            //arg.DictionaryFileName = "AccommodationType";
            //arg.DictionaryFileName = "Careers";
            //arg.DictionaryFileName = "Citys";
            //arg.DictionaryFileName = "IDType";
            //arg.DictionaryFileName = "Nationality";
            arg.Tag = "CSD";
            arg.DictionaryFileName = "Province";
            //arg.DictionaryFileName = "StayPurpose";
            //arg.DictionaryFileName = "Sex";
            OnRequestProcessing(arg);
        }
    }
}
